/**
 * 数组转table
 * @param data 数组
 * @param td_style td的样式
 * @param tr_style tr的样式
 * @param rowmerge 需要合并的行字段
 * @param colmerge 需要合并的列字段(二维数组)
 */
export default function array2table<T>(data: T[], td_style: string, tr_style: string, rowmerge: string[], colmerge: string[]) {
	if (!data || !Array.isArray(data)) {
		return '<table></table>';
	} else {
		const tr_style_str = tr_style ? ` style="${tr_style}"` : '';
		const td_style_str = td_style ? ` style="${td_style}"` : '';
		// get all fields
		const fields = Array.from(data.reduce((m, row) => {
			Object.keys(row).forEach((field) => {
				m.add(field);
			});
			return m;
		}, new Set<string>()));
		const arr = tp(data, rowmerge, colmerge);
		const tb = arr.reduce((trs: any, row: any) => {
			const tds = fields.reduce((colums, field) => {
				const value = row[field] || '';
				if (value !== '' && row[field + 'line'] !== -1 && row[field + 'colum'] !== -1) {
					if (row[field + 'line'] > 1 && row[field + 'colum'] > 1) {
						colums.push(`<td${td_style_str} rowspan='${row[field + 'line']}' colspan='${row[field + 'colum']}'>${value}</td>`);
					} else if (row[field + 'line'] > 1) {
						colums.push(`<td${td_style_str} rowspan='${row[field + 'line']}'>${value}</td>`);
					} else if (row[field + 'colum'] > 1) {
						colums.push(`<td${td_style_str} colspan='${row[field + 'colum']}'>${value}</td>`);
					} else {
						colums.push(`<td${td_style_str}>${value}</td>`);
					}
				}
				return colums;
			}, [] as string[]).join('');
			trs.push(`<tr${tr_style_str}>${tds}</tr>`);
			return trs;
		}, [] as string[]).join('');
		return `<table>${tb}</table>`;
	}
}
function tp(data: any, rowmerge: string[], colmerge: string[]) {
	let first: any = [];
	let last: any = [];
	const arr: any = [];
	const fields = Array.from(data.reduce((m: any, row: any) => {
		Object.keys(row).forEach((field) => {
			m.add(field);
		});
		return m;
	}, new Set<string>()));
	data.forEach((row: any) => {
		fields.forEach((field: any) => {
			const value = row[field] || '';
			const same = JSON.parse('{' + '"' + field + '":"' + value + '","' + field + 'line":' + 1 + ',"' + field + 'colum":' + 1 + '}');
			last.push(same);
		});
		// 将添加的值转成对象
		const json_last = JSON.parse(parsing(last));
		// 列合并
		colmerge.forEach((item: any) => {
			// 那几个列合并
			item.forEach((item_1: any, colindex: number) => {
				// 获取数组里的下一个下标
				const index = colindex + 1;
				// 对象中的属性是数组中的第一个值如果等于对象中的属性是这个值的下一个值
				if (json_last[item[0]] === json_last[item[index]]) {
					// 判断这个列不等于负数
					if (json_last[item_1 + 'colum'] !== -1) {
						json_last[item_1 + 'colum'] += 1;
						json_last[item[colindex + 1] + 'colum'] = -1;
					} else {
						json_last[item[colindex - colindex] + 'colum'] += 1;
						json_last[item[colindex + 1] + 'colum'] = -1;
					}
				} else if (json_last[item_1] === json_last[item[index]]) { // 如果这个属性的值等于下个属性的值
					// 就让这个列加1 下个列等于负数
					json_last[item_1 + 'colum'] += 1;
					json_last[item[index] + 'colum'] = -1;
				}
			});
		});
		// 判断是否是第一次添加
		if (first.length === 0) {
			arr.push(json_last);
		} else {
			// 行合并
			rowmerge.forEach((item: any) => {
				// 如果对象的属性值等于上一个对象的属性值
				if (json_last[item] === first[item]) {
					// 对象的行等于负数
					json_last[item + 'line'] = -1;
					// 获取arr里的最后一个相等的对象下标
					let index = -1;
					// 获取arr里的第一个相等的对象下标
					let a_index = -1;
					arr.forEach((item_1: any, i: number) => {
						// 获取相等对象的下标
						if (item_1[item] === json_last[item]) {
							if (a_index === -1) {
								// 获取第一个相等的对象
								a_index = i;
							}
							// 获取最后一个相等的对象
							index = i;
						}
					});
					// 判断数组中的最后一个相等对象的行是否为负数
					if (arr[index][item + 'line'] === -1) {
						// 如果等于负数就让第一个相等的对象的行加1
						arr[a_index][item + 'line'] += 1;
					} else {
						// 如果不等于负数就让最后一个相等的对象的行加1
						arr[index][item + 'line'] += 1;
					}
				}
			});
			// 将对象添加到数组
			arr.push(json_last);
		}
		// 让对象赋给上一个值
		first = json_last;
		// 数组清空
		last = [];
	});
	return arr;
}

function parsing(data: Array<{}>) {
	let str = '';
	data.forEach((t_item: any, j: number) => {
		if (data.length === 1) {
			str = JSON.stringify(t_item);
		} else if (j === 0) {
			let s = JSON.stringify(t_item);
			s = s.replace('}', ',');
			str += s;
		} else if ((data.length - 1) === j) {
			let s = JSON.stringify(t_item);
			s = s.replace('{', '');
			str += s;
		} else {
			let s = JSON.stringify(t_item);
			s = s.replace('{', '');
			s = s.replace('}', ',');
			str += s;
		}
	});
	return str;
}

